import React, { useEffect, useRef, useState } from 'react';
import Container from './strip-clock.style';

type StripsType = Array<{
	sub: Array<{ value: number, pop: boolean }>,
	transform?: string,
}>

const StripClock: React.FC = () => {

	const [strips, setStrips] = useState<StripsType>([]);
	const isIntersecting = useRef<boolean>(false);
	const loopInterval = useRef<any>(null);
	const containerRef = useRef<HTMLDivElement>(null);
	const stripsRef = useRef<StripsType>([]);
	const numberHeight = useRef(0);

	const init = () => {
		// hrStrips
		let hrStrips: StripsType = [];
		hrStrips[0] = { sub: [] };
		for (let i = 0; i <= 2; i++) {
			hrStrips[0].sub.push({ value: i, pop: false });
		}
		hrStrips[1] = { sub: [] };
		for (let i = 0; i <= 9; i++) {
			hrStrips[1].sub.push({ value: i, pop: false });
		}
		// minStrips
		let minStrips: StripsType = [];
		minStrips[0] = { sub: [] };
		for (let i = 0; i <= 5; i++) {
			minStrips[0].sub.push({ value: i, pop: false });
		}
		minStrips[1] = { sub: [] };
		for (let i = 0; i <= 9; i++) {
			minStrips[1].sub.push({ value: i, pop: false });
		}
		// secStrips
		let secStrips: StripsType = [];
		secStrips[0] = { sub: [] };
		for (let i = 0; i <= 5; i++) {
			secStrips[0].sub.push({ value: i, pop: false });
		}
		secStrips[1] = { sub: [] };
		for (let i = 0; i <= 9; i++) {
			secStrips[1].sub.push({ value: i, pop: false });
		}
		stripsRef.current = [...hrStrips, ...minStrips, ...secStrips];
	}

	const update = () => {
		setStrips([...stripsRef.current]);
	}

	const highlight = (strip: number, d: number) => {
		stripsRef.current[strip].sub[d].pop = true;
		update();
		setTimeout(() => {
			stripsRef.current[strip].sub[d].pop = false;
			update();
		}, 950);
	}

	const stripSlider = (strip: number, number: number) => {
		let d1 = Math.floor(number / 10);
		let d2 = number % 10;
		stripsRef.current[strip].transform = `translateY(${d1 * -numberHeight.current}px)`;
		highlight(strip, d1);
		stripsRef.current[strip + 1].transform = `translateY(${d2 * -numberHeight.current}px)`;
		highlight(strip + 1, d2);
		update();
	}

	const render = () => {
		if (!isIntersecting.current) {
			return;
		}
		const time = new Date();
		const hours = time.getHours();
		const mins = time.getMinutes();
		const secs = time.getSeconds();
		stripSlider(0, hours);
		stripSlider(2, mins);
		stripSlider(4, secs);
	}

	const loopControl = (run: boolean) => {
		if (run) {
			clearInterval(loopInterval.current);
			loopInterval.current = setInterval(() => render(), 1000);
			render();
		} else {
			clearInterval(loopInterval.current);
			loopInterval.current = null;
		}
	}

	useEffect(() => {
		init();
		update();
		const intersectionObserver = new IntersectionObserver((entries) => {
			if (!Array.isArray(entries) || !entries.length) {
				return;
			}
			for (let entry of entries) {
				isIntersecting.current = entry.isIntersecting;
				loopControl(isIntersecting.current);
			}
		});
		containerRef.current && intersectionObserver.observe(containerRef.current);
		return () => {
			containerRef.current && intersectionObserver.unobserve(containerRef.current);
			loopControl(false);
		}
	}, []);

	return (
		<Container onNumberHeightChange={(e) => numberHeight.current = e}>
			<div className='clock' ref={containerRef}>
				<div className='hr'>
					<div className='strip' style={{ transform: strips[0]?.transform }}>
						{strips[0]?.sub.map((each, i) => {
							return (
								<div className={`number ${each.pop ? 'pop' : ''}`} key={i}>{each.value}</div>
							);
						})}
					</div>
					<div className='strip' style={{ transform: strips[1]?.transform }}>
						{strips[1]?.sub.map((each, i) => {
							return (
								<div className={`number ${each.pop ? 'pop' : ''}`} key={i}>{each.value}</div>
							);
						})}
					</div>
				</div>
				<div className='min'>
					<div className='strip' style={{ transform: strips[2]?.transform }}>
						{strips[2]?.sub.map((each, i) => {
							return (
								<div className={`number ${each.pop ? 'pop' : ''}`} key={i}>{each.value}</div>
							);
						})}
					</div>
					<div className='strip' style={{ transform: strips[3]?.transform }}>
						{strips[3]?.sub.map((each, i) => {
							return (
								<div className={`number ${each.pop ? 'pop' : ''}`} key={i}>{each.value}</div>
							);
						})}
					</div>
				</div>
				<div className='sec'>
					<div className='strip' style={{ transform: strips[4]?.transform }}>
						{strips[4]?.sub.map((each, i) => {
							return (
								<div className={`number ${each.pop ? 'pop' : ''}`} key={i}>{each.value}</div>
							);
						})}
					</div>
					<div className='strip' style={{ transform: strips[5]?.transform }}>
						{strips[5]?.sub.map((each, i) => {
							return (
								<div className={`number ${each.pop ? 'pop' : ''}`} key={i}>{each.value}</div>
							);
						})}
					</div>
				</div>
			</div>
		</Container>
	)

}

export default StripClock;
